#pragma once
#include <stb_image.h>
#include <vulkan/vulkan_raii.hpp>

namespace Lumine
{
    class LumineTexture
    {
    protected:
        vk::raii::Image textureImage = nullptr;
        vk::raii::DeviceMemory m_memory = nullptr;
        vk::raii::ImageView m_imageView = nullptr;
        vk::raii::Sampler m_sampler = nullptr;
        vk::Format m_format = vk::Format::eR8G8B8A8Srgb;

        void createImage(uint32_t width, uint32_t height, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags properties, vk::raii::Image &image, vk::raii::DeviceMemory &imageMemory);

        virtual void createTextureImage() {}

        stbi_uc *loadPixels(const std::string &path, int &w, int &h, vk::DeviceSize size);

        void transitionImageLayout(const vk::raii::Image &image, vk::ImageAspectFlags aspect, vk::ImageLayout oldLayout, vk::ImageLayout newLaoyout);

        void copyBufferToImage(const vk::raii::Buffer &buffer, vk::raii::Image &image, uint32_t width, uint32_t height);

    public:
        LumineTexture() = default;
        LumineTexture(const LumineTexture &) = delete;
        LumineTexture &operator=(const LumineTexture &) = delete;
        // 允许移动操作：让编译器生成默认的移动构造函数和移动赋值运算符
        // 这对于 RAII 对象是必须的，因为它转移了底层 Vulkan 句柄的所有权
        LumineTexture(LumineTexture &&) = default;
        LumineTexture &operator=(LumineTexture &&) = default;

        virtual void Create() {};
        const void SetFormat(vk::Format format) { m_format = format; }
        const vk::Format Format() { return m_format; }
        const vk::raii::Sampler &Sampler() const { return m_sampler; }
        const vk::raii::ImageView &ImageView() const { return m_imageView; }
        const vk::raii::Image &Image() const { return textureImage; }
    };

}